#include <stdio.h>
#include "davinci-intc.h"
#include "davinci-timer.h"
#include "addressmap.h"
#include "davinci.h"


void log(char *,...);

#define N_TIMERS 4
static union 
{
	struct davinci_timer dat;
	unsigned int w[1];
	unsigned char b[1];
	unsigned short s[1];
}timer [N_TIMERS];


void davinci_timer_handler(
	  void *lpContext,
	  int op, 
	  unsigned int dwAddress,   // start dwAddress on 32bit bus
	  char *pszBuff,           // optional 
	  unsigned int nBytes )    // in or out buffer
{
	int n_channel=*(char *)(lpContext);
	int offset;

	offset=dwAddress&0x3ff;
	 if(n_channel<N_TIMERS/*&&(offset)<DAVINCI_TIMER_ADDR_SIZE*/)
	 {
	
	
		 		 if(op==ADDR_RANGE_WRITE)
		 log("TIMER %d: w %x %x,%x\n",n_channel,dwAddress,offset,*(__u32 *)pszBuff);
		 switch(op)
		 {
		 case ADDR_RANGE_READ:  
			 for(int i=0;i<nBytes;i++)
			 {
				 pszBuff[i]=timer[n_channel].b[i+offset];

			 }
			 break;
		 case ADDR_RANGE_WRITE: 
			 for(int i=0;i<nBytes;i++)
			 {
				 timer[n_channel].b[i+offset]=pszBuff[i];

			 }
			 break;
		 default:
			 return;

		 }
		 if(op==1)
		 log("TIMER %d: r %x %x,%x\n",n_channel,dwAddress,offset,*(__u32 *)pszBuff);
	 }
	 //log("TIMER%d:%x %x %x\n",n_channel,op,dwAddress,nBytes);
}


int freq_f;
void davinci_timer_do_clock()
{
	//if(freq_f!=1000)
	//freq_f++;
	//else
	{
		for(int i=0;i<N_TIMERS;i++)
		{
			timer[i].dat.tim12++;

			if((__u16)timer[i].dat.tim12==0)
			{
				timer[i].dat.tim34++;
			}
		}



		if((__u16)timer[0].dat.tim12==0)
		assert_irq(IRQ_TINTL0);
		if((__u16)timer[0].dat.tim34==0)
		assert_irq(IRQ_TINTH0);

		if((__u16)timer[1].dat.tim12==0)
		assert_irq(IRQ_TINTL1);
		if((__u16)timer[1].dat.tim34==0)
		assert_irq(IRQ_TINTH1);

		if((__u16)timer[2].dat.tim12==(__u16)timer[2].dat.prd12
			&&(__u16)timer[2].dat.tim34==(__u16)timer[2].dat.prd34)
		assert_irq(IRQ_WDINT);
	}

}